require('dotenv').config();
const mongoose = require('mongoose');
const http = require('http');
const app = require('./app');
const User = require('./models/User');
const server = http.createServer(app);
const PORT = process.env.PORT || 3000;


mongoose.connect(process.env.MONGO_URI)
  .then(() => {
    server.listen(PORT, () => {
      console.log(`🚀 Server running on http://localhost:${PORT}`);
    });
  })
  .catch((err) => console.error(err));

// 初始化 Socket.IO
const { Server } = require('socket.io');
const { registerChatEvents } = require('./socket/chatHandler');

const io = new Server(server, {
  cors: {
    origin: '*',
  }
});

const onlineUsers = new Set();

io.on('connection', (socket) => {
  console.log('客户端连接:', socket.id);
  socket.on('login', async ({ userId, password }) => {
    try {
      const user = await User.findOne({ userId });
      if (!user) {
        socket.emit('loginResult', {
          success: false,
          message: '用户不存在'
        });
        return;
      }

      console.log(password);
      const match = password === user.password;
      if (!match) {
        socket.emit('loginResult', {
          success: false,
          message: '密码错误'
        });
        return;
      }

      socket.emit('loginResult', {
        success: true,
        nickname: user.nickname,
        userId: user.userId,
        avatar: user.avatar
      });
    } catch (err) {
      console.error('登录出错:', err);
      socket.emit('loginResult', {
        success: false,
        message: '服务器错误，请稍后再试'
      });
    }
  });

  socket.on('addFriend', async ({ userId, friendId }) => {
    const friendUser = await User.findOne({ userId: friendId });
    if (!friendUser) {
      socket.emit('addFriendResult', { success: false, message: '用户不存在' });
      return;
    }

    const success = await User.addFriend(userId, friendId);
    await User.addFriend(friendId, userId);
    socket.emit('addFriendResult', {
      success,
      friendId,
      message: success ? null : '好友已存在或添加失败'
    });
  });

  // 注册事件
  socket.on('register', async ({ userId, nickname, email, password }) => {
    try {
      const existing = await User.findOne({ userId });

      if (existing) {
        socket.emit('registerResult', {
          success: false,
          message: '该用户 ID 已存在'
        });
        return;
      }

      const newUser = new User({ userId, nickname, email, password, friends: [{'userId': 'admin', 'remark': ''}] });
      await newUser.save();

      socket.emit('registerResult', {
        success: true,
        userId,
        nickname
      });

      await User.addFriend('admin', userId);
    } catch (error) {
      console.error('注册出错:', error);
      socket.emit('registerResult', {
        success: false,
        message: '服务器错误，请稍后再试'
      });
    }
  });

  const { getFriendList } = require('./utils/friendUtils');
  socket.on('getFriends', async (userId) => {
    try {
      const friendList = await getFriendList(userId);
      socket.emit('friendList', friendList);
    } catch (err) {
      console.error('获取好友列表出错:', err);
      socket.emit('friendList', []);
    }
  });

  socket.on('online', async ({userId, nickname}) => {
    socket.userId = userId; // 绑定userId到socket
    socket.userNickname = nickname; // 绑定昵称到socket
    socket.join(userId);
    onlineUsers.add(userId);
    console.log(`用户 ${nickname} 上线`); // 加入在线集合
    // console.log(io.sockets.adapter.rooms);

    const friends = await getFriendList(userId);
    friends.forEach(friend => {
      // 通知好友上线
      // console.log(`通知好友 ${friend.userId} 用户 ${userId} 上线`);
      io.to(friend.userId).emit('friendOnline', { userId });
    });
  });
  registerChatEvents(io, socket); // 注册聊天相关事件

  socket.on('disconnect', async () => {
    if (!socket.userId) {
      return;
    }
    onlineUsers.delete(socket.userId); // 下线时移除
    console.log(`🔴 用户${socket.userNickname}下线`);

    const friends = await getFriendList(socket.userId);
    friends.forEach(friend => {
      io.to(friend.userId).emit('friendOffline', { userId: socket.userId });
    });
  });

  socket.on('isOnline', (userId, callback) => {
    callback(onlineUsers.has(userId));
  });
});